#pragma once


//-----------------------------------------------------------------------------
//															Vector2 class
//-----------------------------------------------------------------------------
template <typename T>
class Vector2
{
public:
	Vector2();
	Vector2(T _x, T _y);
	Vector2(const Vector2<T>& v);

	//	casting operators
	operator float* ();
	operator const float* () const;

	//	assignment operators
	Vector2<T>& operator= (const Vector2<T>& rhs);
	Vector2<T>& operator+= (const Vector2<T>& rhs);
	Vector2<T>& operator-= (const Vector2<T>& rhs);
	Vector2<T>&	operator*= (T rhs);
	Vector2<T>&	operator/= (T rhs);

	//	unary operators
	Vector2<T> operator+ () const;
	Vector2<T> operator- () const;

	//	binary operators
	Vector2<T>	operator+ (const Vector2<T>& rhs) const;
	Vector2<T>	operator- (const Vector2<T>& rhs) const;

	friend Vector2<T> operator* (T number, const Vector2<T>& vector);

	//	equality operators
	bool operator== (const Vector2<T>& rhs) const;
	bool operator!= (const Vector2<T>& rhs) const;

public:
	T	x;
	T y;
};

//	typedefs
typedef Vector2<float>	Vec2;
typedef	Vector2<int>		Vec2i;

//-----------------------------------------------------------------------------
//															Vector3 class
//-----------------------------------------------------------------------------
template <typename T>
class Vector3
{
public:
	Vector3();
	Vector3(T _x, T _y, T _z);
	Vector3(const Vector3<T>& v);

	//	casting operators
	operator float* ();
	operator const float* () const;

	//	assignment operators
	Vector3<T>& operator= (const Vector3<T>& rhs);
	Vector3<T>& operator+= (const Vector3<T>& rhs);
	Vector3<T>& operator-= (const Vector3<T>& rhs);
	Vector3<T>&	operator*= (T rhs);
	Vector3<T>&	operator/= (T rhs);

	//	unary operators
	Vector3<T> operator+ () const;
	Vector3<T> operator- () const;

	//	binary operators
	T						operator* (const Vector3<T>& rhs) const;	//	dot product
	Vector3<T>	operator^ (const Vector3<T>& rhs) const;	//	cross product
	Vector3<T>	operator+ (const Vector3<T>& rhs) const;
	Vector3<T>	operator- (const Vector3<T>& rhs) const;

	friend Vector3<T> operator* (T number, const Vector3<T>& vector);

	//	equality operators
	bool operator== (const Vector3<T>& rhs) const;
	bool operator!= (const Vector3<T>& rhs) const;

	//	math operations
	T						length() const;
	void				normalize();
	Vector3<T>	normalized() const;
	Vector3<T>	cross(const Vector3<T>& v);
	T						dot(const Vector3<T>& v);

public:
	T	x;
	T	y;
	T	z;
};


//	typedefs
typedef Vector3<float>	Vec3;

//-----------------------------------------------------------------------------
//																Vector4 class
//-----------------------------------------------------------------------------
template <typename T>
class Vector4
{
public:
	Vector4();
	Vector4(T _x, T _y, T _z, T _w);

public:
	T	x;
	T	y;
	T	z;
	T w;
};

//	typedefs
typedef Vector4<float>	Vec4;


//-----------------------------------------------------------------------------
//	implementation
//-----------------------------------------------------------------------------
#include "Vector.inl"